package com.dayuanit.booksystem.v2.util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

/**
 * DB 工具类
 */
public class DataBaseUtil {
    //Connection集合  就是个连接池  Connection是独占式使用，并且是可以复用。由于Connection相当于一个TCP/IP连接，
    // 比较耗性能，所以提前创建一批Connection放到集合中，这就是所谓的池技术，连接池。还比如线程有线程池。
    //ArrayList不是线程安全的，在多个线程同时对其添加或者移除操作，有可能会抛异常。
    //需要一个能够在多线程情况下正常工作的结合。
//    private static List<Connection> connectionList = new ArrayList<>();

    //把集合换成线程安全的集合
    private static List<Connection> connectionList = new Vector();

    //最大连接数  配置在文件中 做到可配置化
    public static int TOTAL_MAX_CONNECITON = 2;

    //不能够共用，只能够独用
    private static String url;
    private static String username;
    private static String password;

    static {
        try {
            initDB();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void initDB() throws Exception {
        InputStream resourceAsStream = DataBaseUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);

        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
        //从配置文件中 读取最大连接数
        TOTAL_MAX_CONNECITON = Integer.parseInt(properties.getProperty("total_max_connection"));

        //加载数据库驱动包的Driver类，具体作用是：从cp中加载驱动类，并将其初始化，也就是会执行类的静态代码块，
        //mysqlSQL的Driver类静态代码块会创建自己，并将自己注册到DriverManager中的线程安全集合中；然后，DriverManger才能通过
        //getConnection方法，依据你的URL地址来找到匹配的驱动类。
        //JDBC4.0之后，class.forName可以不用写，写了也没错。
        //JDBC.4.0之后，采取了SPI的方式由JDK自动将驱动加载到jvm内存，并将其初始化。
        Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");

        for (int i=0; i<TOTAL_MAX_CONNECITON; i++) {
            Connection connection = DriverManager.getConnection(url, username, password);
            System.out.println(">>>>>Connection子类：" + connection.getClass().getName());
            connectionList.add(connection);
        }
    }

    /**
     * 提供Connection数据库连接 默认不开启事务
     * @return
     */
    public static Connection getConnection() {
        return getConnection(true);
    }

    public static  Connection getConnection(boolean autoCommit) {
        if (connectionList.isEmpty()) {
            return null;
        }
        //使用remove是真的从集合中移除掉，这样就不会有其他人和我使用一个connection
        Connection connection = connectionList.remove(0);
        try {
            //TODO 真正的连接池 还需要对连接进行校验
            connection.createStatement().executeQuery("select 1");

            connection.setAutoCommit(autoCommit);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 把Connction连接还到池中
     * @param connection
     */
    public static  void close(Connection connection) {
        if (connection == null) {
            return;
        }
        connectionList.add(connection);
    }

    /**
     * 当我们的系统不在运行的，那就可以条用此方法，将所有的连接关闭。
     */
    public static void close() {
        for (Connection connection : connectionList) {
            try {
                if (!connection.isClosed()) {
                    connection.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void commit(Connection connection) {
        try {
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void rollback(Connection connection) {
        try {
            connection.rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
